package cn.good.yan.service.impl;

import cn.good.yan.service.T1Service;
import cn.hutool.core.util.IdUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.concurrent.TimeUnit;

/**
 * 演示：正常的请求
 *      1 、2 服务降级
 *      3 服务熔断
 * @author shengren.yan
 * @create 2023-12-27
 */
@Service
public class T1ServiceImpl implements T1Service {

    /**
     * 1 正常访问一切 OK
     *
     * @param id
     * @return
     */
    @Override
    public String paymentInfoOk(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + "正常请求,id: " + id + "\t" + "O(∩_∩)O";
    }

    /**
     * 2 超时访问，演示降级 - 延迟5分钟
     *
     * @param id
     * @return
     */
    @Override
    public String paymentInfoTimeOut(Integer id) {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + "超时请求,id: " + id + "\t" + "O(∩_∩)O，耗费3秒";

    }

    /**
     * 超时访问，演示降级 - 延迟5分钟  （但一般降级处理，是在客户端这边处理）
     *  演示2：
     *      fallbackMethod = 降级方法
     *      HystrixProperty 指定超时时间，为3000
     *      启动类 ： 增加 @EnableCircuitBreaker 注解
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "doJangji", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public String paymentInfoTimeOut2(Integer id) {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + "超时等待,id: " + id + "\t" + "O(∩_∩)O，耗费3秒";

    }

    /**
     * 超时访问的降级方法  - 降级的方法
     *
     * @param id
     * @return
     */
    public String doJangji(Integer id) {
        // 降级方法入口
        return "/(ㄒoㄒ)/调用支付接口超时或异常：\t" + "\t当前线程池名字" + Thread.currentThread().getName();
    }


    /**
     * 3 服务熔断
     *      fallbackMethod 熔断的处理类
     *      在10秒 的时间内，必须达到20次请求，失败达到60次的比例，就触发熔断，下次请求，直接进行降级处理
     * @param id
     * @return {@link String}
     */
    @HystrixCommand(fallbackMethod = "payBreakerFallback", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),                    // 是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"),       // 请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),     // 失败率达到多少后跳闸
    })
    @Override
    public String payBreaker(@PathVariable("id") Integer id) {
        if (id < 0) {
            throw new RuntimeException("******id 不能负数");
        }
        String serialNumber = IdUtil.simpleUUID(); // uuid
        return Thread.currentThread().getName() + "\t" + "调用成功，流水号: " + serialNumber;
    }

    /**
     * 该服务降级的处理类
     *
     * @param id
     * @return {@link String}
     */
    public String payBreakerFallback(@PathVariable("id")  Integer id) {
        return "id 不能负数，请稍后再试，/(ㄒoㄒ)/~~   id: " + id;
    }

}
